﻿Namespace Functions

    ''' <summary>List of Namespaces</summary>
    Public Class MetisNamespaceList
        Inherits MetisSortedEntityList(Of IMetisNamespaceReference)

        Private _MetisCore As MetisCore
        Private _Parent As MetisNamespace

        ''' <summary>Creates a new NamespaceList and loads all Namespaces from the DB.</summary>
        ''' <param name="MetisCore">Reference to the central management object of Metis that manages the access to the DB.</param>
        Sub New(ByVal MetisCore As MetisCore)
            _MetisCore = MetisCore

            Dim OraReader As OracleDataReader
            Dim OraCmd As OracleCommand
            OraCmd = New OracleCommand("SELECT namespace_id, description, annotation, NVL(parent_namespace_fk,-1) " & _
                                        "FROM dam_namespaces " & _
                                        "CONNECT BY PRIOR namespace_id=parent_namespace_fk START WITH parent_namespace_fk IS NULL " & _
                                        "ORDER BY level, description", _MetisCore.Connection)

            OraReader = OraCmd.ExecuteReader
            Do While OraReader.Read
                Dim tmpParenNamespace As MetisNamespace = Find(OraReader.GetInt32(3))
                Dim tmpAnnotation As String = If(OraReader.IsDBNull(2), "", OraReader.GetString(2))

                Dim tmpNamespace As New MetisNamespace(_MetisCore, OraReader.GetInt32(0), OraReader.GetString(1), tmpParenNamespace, tmpAnnotation)

                If tmpParenNamespace IsNot Nothing Then
                    tmpParenNamespace.Children.Add(tmpNamespace)
                Else
                    Me.Add(tmpNamespace)
                End If
            Loop
            OraReader.Close()
        End Sub

        ''' <summary>Creates a new NamespaceList</summary>
        ''' <param name="MetisCore">Reference to the central management object of Metis that manages the access to the DB.</param>
        ''' <param name="Parent">Reference to its parent Namespace</param>
        ''' <remarks>No further action (load from DB) will be taken.</remarks>
        Sub New(ByVal MetisCore As Core.MetisCore, ByVal Parent As MetisNamespace)
            _MetisCore = MetisCore
            _Parent = Parent
        End Sub

        Private Sub HandleListItemPropChange(ByVal sender As Object, ByVal e As System.ComponentModel.ListChangedEventArgs) Handles Me.ListChanged
            If e.ListChangedType = System.ComponentModel.ListChangedType.ItemChanged AndAlso _
               e.PropertyDescriptor IsNot Nothing AndAlso e.PropertyDescriptor.Name = "Name" Then
                SetItem(e.NewIndex, Me(e.NewIndex))
            End If
        End Sub

        ''' <summary>Inserts a new Namespace into the List.</summary>
        ''' <param name="index">The Index where the new item should be added.</param>
        ''' <param name="item">The Namespace to add.</param>
        ''' <remarks>The Namespace will be added at the position of its alphabetical order (by its name) within the list, no matter what index was specified</remarks>
        ''' <exception cref="Core.Exceptions.DublicateNameException">Raised when the name of the inserted Namespace is already used in the list.</exception>
        Protected Overrides Sub InsertItem(ByVal index As Integer, ByVal item As IMetisNamespaceReference)
            MyBase.InsertItem(index, item)
            If (_Parent IsNot Nothing AndAlso Not _Parent.Equals(item.Namespace)) OrElse _Parent Is Nothing Then item.Namespace = _Parent
        End Sub

        Protected Overrides Sub SetItem(ByVal index As Integer, ByVal item As IMetisNamespaceReference)
            MyBase.SetItem(index, item)
            If (_Parent IsNot Nothing AndAlso Not _Parent.Equals(item.Namespace)) OrElse _Parent Is Nothing Then item.Namespace = _Parent
        End Sub

        Public ReadOnly Property Parent() As MetisNamespace
            Get
                Return _Parent
            End Get
        End Property

        ''' <summary>
        ''' Helpfunction for <see cref="MetisNamespace.Reload"/> to sync the in-memory representation of the Namespaces with the state of the DB
        ''' </summary>
        ''' <param name="Namespaces">The current (old) state of the Namespaces that are updated</param>
        ''' <param name="ReferenceList">The Last loaded state of the DB</param>
        Private Sub RemoveListItems(ByVal Namespaces As MetisNamespaceList, ByVal ReferenceList As MetisNamespaceList)
            'Remove deleted namespaces
            For i As Integer = Namespaces.Count - 1 To 0 Step -1
                If Namespaces(i).ID >= 0 Then
                    Dim tmpNS As MetisNamespace = ReferenceList.Find(Namespaces(i).ID)
                    If tmpNS Is Nothing OrElse _
                       (tmpNS.Parent Is Nothing AndAlso Namespaces(i).Namespace IsNot Nothing) OrElse _
                       (tmpNS.Parent IsNot Nothing AndAlso Not tmpNS.Parent.Equals(Namespaces(i).Namespace)) Then
                        Namespaces.RemoveAt(i)
                    Else
                        'RemoveListItems(Namespaces(i).Children, ReferenceList)
                    End If
                End If
            Next
        End Sub

        ''' <summary>
        ''' Helpfunction for <see cref="MetisNamespace.Reload"/> to sync the in-memory representation of the Namespaces with the state of the DB
        ''' </summary>
        ''' <param name="Namespaces">The current (old) state of the Namespaces that are updated</param>
        ''' <param name="ReferenceList">The Last loaded state of the DB</param>
        Private Sub AddListItems(ByVal Namespaces As MetisNamespaceList, ByVal ReferenceList As MetisNamespaceList)
            'Add new dimensions or update if allready existing (and loaded)
            For Each Item As MetisNamespace In ReferenceList
                Dim tmpNS As MetisNamespace = Namespaces.Find(Item.ID)
                If tmpNS Is Nothing OrElse Not Item.Equals(tmpNS.Parent) Then

                End If
            Next
        End Sub

        Public Overrides Sub Reload()
            Dim tmpNSList As New MetisNamespaceList(_MetisCore)
            'AddListItems(Me, tmpNSList)
            'RemoveListItems(Me, tmpNSList)
        End Sub

        Public Overrides Function Find(ByVal ID As Integer) As IMetisNamespaceReference
            For Each Item As IMetisNamespaceReference In Me
                If Item.ID = ID Then
                    Return Item
                ElseIf TypeOf Item Is MetisNamespace Then
                    Dim tmpNamespace As MetisNamespace = DirectCast(Item, MetisNamespace).Children.Find(ID)
                    If tmpNamespace IsNot Nothing Then Return tmpNamespace
                End If
            Next
            Return Nothing
        End Function

    End Class
End Namespace

